package simulation;

import streaming.Host;
import streaming.Overlay;

public class OverrideMessage implements EventHandler {

	Host source;
	Host dest;
	int oldSeqNo, newSeqNo;
	String data;

	public OverrideMessage(Host newSource, Host newDest, int newOldSeqNo, int newNewSeqNo, String data){
		this.setSource(newSource);
		this.setDest(newDest);
		this.setData(data);
		
		// If the source doesn't have the destination as a neighbor anymore (due to node removal, for example), ignore this message
		if (this.getSource().getNeighborsMap().containsKey(this.getDest().getId())){
		
			double latency = this.getSource().getNeighborLatency(this.getDest().getId());
			
			if (latency == -1) {
				latency = Overlay.getInstance().getLatency(this.getSource(), this.getDest());
				this.getSource().setNeighborLatency(this.getDest().getId(), latency);
				
				// Source's neighbors are not reciprocal
				if (this.getSource().getId() != 0) {
					this.getDest().setNeighborLatency(this.getSource().getId(), latency);
				}
			}
			// Put receipt of packet in the queue
			Simulator sim = Simulator.getInstance();
			sim.addEvent(sim.getTime() + latency, this) ;
			this.setNewSeqNo(newNewSeqNo);
			this.setOldSeqNo(newOldSeqNo);
		}
		else {
			System.out.println("Host " + this.getDest().getId() + " couldn't be found, isn't anymore a neighbor of host "+ this.getSource().getId());
		}
	}
	
	// Receipt of packet
	public void run(double time){
		if (dest.getId() == -1)
			return;
		dest.handleOverride(oldSeqNo, newSeqNo, source, data);
	}

	/* Getters and Setters */
	
	public Host getSource() {
		return source;
	}

	public void setSource(Host source) {
		this.source = source;
	}

	public Host getDest() {
		return dest;
	}

	public void setDest(Host dest) {
		this.dest = dest;
	}

	public int getOldSeqNo() {
		return oldSeqNo;
	}

	public void setOldSeqNo(int oldSeqNo) {
		this.oldSeqNo = oldSeqNo;
	}

	public int getNewSeqNo() {
		return newSeqNo;
	}

	public void setNewSeqNo(int newSeqNo) {
		this.newSeqNo = newSeqNo;
	}

	public String getData() {
		return data;
	}

	public void setData(String data) {
		this.data = data;
	}
}
